在 Astro 中,佈局是一種特殊的組件,旨在提供可重複使用的 UI 結構,通常用於頁面模板。我們經常使用 "佈局" 一詞來指稱提供頁面中共享元素的 Astro 組件,例如頁首 (header)
、導航欄
和頁尾 (footer)
。一個典型的 Astro 佈局組件可以為 Astro``、Markdown
或 MDX
頁面提供以下內容:
<html>
、<head>
和 <body>
標籤)。<slot />
,用於指定個別頁面內容應該注入的位置。但是,佈局組件並不限於此!它們可以像任何其他 Astro 組件一樣接受 props,導入和使用其他組件,包括 UI 框架組件和客戶端腳本。您甚至可以將佈局組件視為部分 UI 模板,它們不必提供完整的頁面外殼。
通常,佈局組件被放置在 Astro 項目的 src/layouts
目錄中以便更好地組織程式碼,但這不是強制性的。您可以選擇將它們放在項目的任何位置。如果需要,您還可以將佈局組件與頁面一起放在一起,只需在佈局名稱前添加下劃線 _
。
以下是一個 layout 的範例:
<!-- layouts/MySiteLayout.astro -->
---
import BaseHead from '../components/BaseHead.astro';
import Footer from '../components/Footer.astro';
const { title } = Astro.props
---
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<BaseHead title={title}/>
</head>
<body>
<nav>
<a href="#">Home</a>
<a href="#">Posts</a>
<a href="#">Contact</a>
</nav>
<h1>{title}</h1>
<article>
<slot /> <!-- 個別頁面內容將在此處插入 -->
</article>
<Footer />
</body>
</html>
接著使用上面的佈局組件,只需在頁面內容中引用它們即可,並傳遞所需的 props
。
---
import MySiteLayout from '../layouts/MySiteLayout.astro';
---
<MySiteLayout title="Home Page">
<p>My page content, wrapped in a layout!</p>
</MySiteLayout>
佈局對於 Markdown 和 MDX 頁面特別有用,否則這些頁面將沒有任何頁面格式。
在 Markdown 和 MDX 文件中,可以使用 layout 屬性來指定頁面使用的佈局組件。這個 layout 屬性可以接受來自頁面 frontmatter 的值,讓您可以動態指定佈局。
以下是一個示例 Markdown 文件中的 layout
屬性的使用:
---
layout: ../layouts/BaseLayout.astro
title: "Hello, World!"
author: "Matthew Phillips"
date: "09 Aug 2022"
---
frontmatter
和其他數據。<slot />
:指示 Markdown/MDX 內容應該呈現的位置。以下是一個示例 Markdown
佈局組件的結構:
---
// 1. frontmatter prop用於訪問frontmatter和其他數據
const { frontmatter } = Astro.props;
---
<html>
<head>
<!-- 在此處添加其他Head元素,例如樣式和meta標籤。 -->
<title>{frontmatter.title}</title>
</head>
<body>
<!-- 在此處添加其他UI組件,例如常見的頁首和頁尾。 -->
<h1>{frontmatter.title} by {frontmatter.author}</h1>
<!-- 2. 渲染的HTML將傳遞到默認插槽。 -->
<slot />
<p>Written on: {frontmatter.date}</p>
</body>
</html>
對於 Markdown 和 MDX 佈局,Astro 提供了一系列有用的 props,這些 props 允許您輕鬆訪問有關頁面的信息。
以下是這些 props 的詳細說明:
以下是範例是 Markdown
或 MDX
佈局中可能會傳遞給 Astro.props 的資訊:
Astro.props = {
file: "/home/user/projects/.../file.md",
url: "/en/guides/markdown-content/",
frontmatter: {
/** 部落格文章的frontmatter */
title: "Astro 0.18 Release",
date: "Tuesday, July 27 2021",
author: "Matthew Phillips",
description: "Astro 0.18 is our biggest release since Astro launch.",
/** 生成的值 */
file: "/home/user/projects/.../file.md",
url: "/en/guides/markdown-content/"
},
headings: [
{
"depth": 1,
"text": "Astro 0.18 Release",
"slug": "astro-018-release"
},
{
"depth": 2,
"text": "Responsive partial hydration",
"slug": "responsive-partial-hydration"
}
/* ... */
],
/** 僅適用於Markdown */
rawContent: () => "# Astro 0.18 Release\nA little over a month ago, the first public beta [...]",
compiledContent: () => "<h1>Astro 0.18 Release</h1>\n<p>A little over a month ago, the first public beta [...]</p>",
}
如果需要向 MDX 佈局傳遞一些不能或不應存在於 frontmatter 中的信息,您可以導入並像任何其他組件一樣使用 <Layout />
組件,然後傳遞這些額外的 props。
如以下範例:
---
layout: '../../layouts/BaseLayout.astro'
title: 'My first MDX post'
publishDate: '21 September 2022'
---
import BaseLayout from '../../layouts/BaseLayout.astro';
function fancyJsHelper() {
return "Try doing that with YAML!";
}
<BaseLayout title={frontmatter.title} fancyJsHelper={fancyJsHelper}>
Welcome to my new Astro blog, using MDX!
</BaseLayout>
然後,您可以在佈局中通過 Astro.props
使用這些值,MDX 內容將注入到您的 <slot />
組件所指定的位置中。
如下:
---
const { title, fancyJsHelper } = Astro.props;
---
<!-- -->
<h1>{title}</h1>
<slot /> <!-- 個別頁面內容將在此處注入 -->
<p>{fancyJsHelper()}</p>
<!-- -->
一個 Astro 佈局組件可以編寫為接收來自.md
和.mdx
文件的 frontmatter 對象,以及來自.astro 文件傳遞的任何命名 props。
在以下示例中,佈局將從頂層 frontmatter 或 Astro.props 中顯示頁面標題:
---
const { title } = Astro.props.frontmatter || Astro.props;
---
<html>
<head></head>
<body>
<h1>{title}</h1>
<slot />
</body>
</html>
佈局組件不必包含整個頁面的 HTML,它們可以進一步拆分為較小的組件,以實現更靈活的頁面模板。這在需要共享程式碼時非常有用。
例如,您可以使用一個名為 BlogPostLayout.astro
的佈局組件為文章的標題、日期和作者添加樣式,然後再使用一個名為 BaseLayout.astro
的佈局組件處理頁面的其餘部分,例如導航、頁尾、SEO 元標籤、全局樣式和字體。這樣的方式,您可以輕鬆將從文章接收的 props 傳遞到其他佈局,就像處理任何其他嵌套組件一樣。
---
import BaseLayout from './BaseLayout.astro'
const {frontmatter} = Astro.props;
---
<BaseLayout url={frontmatter.url}>
<h1>{frontmatter.title}</h1>
<h2>Post author: {frontmatter.author}</h2>
<slot />
</BaseLayout>
本文介紹了 Astro 的佈局系統,用於提供可重複使用的 UI 結構,通常用於頁面模板。您已經學會了如何在 Astro 項目中定義佈局,並如何透過 frontmatter 或 props 從 Markdown、MDX 和 Astro 頁面中訪問這些佈局。這將有助於更好地組織您的程式碼,使您的項目更加靈活和易於維護。